package com.mybatisflex.kotlin.ksp.internal.gen.tables

import com.google.devtools.ksp.symbol.KSFile
import com.mybatisflex.kotlin.ksp.internal.config.flex.AllInTablesClassName
import com.mybatisflex.kotlin.ksp.internal.config.flex.AllInTablesEnable
import com.mybatisflex.kotlin.ksp.internal.config.flex.AllInTablesPackage
import com.mybatisflex.kotlin.ksp.internal.util.TablesPropertyNamer
import com.mybatisflex.kotlin.ksp.internal.util.suppressDefault
import com.mybatisflex.kotlin.ksp.internal.util.write
import com.mybatisflex.kotlin.ksp.logger
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.PropertySpec
import com.squareup.kotlinpoet.TypeSpec


internal class TablesGenerator(private val properties: List<PropertySpec>, private vararg val files: KSFile) {
    companion object {
        private var isExists = false  // 此属性用于判断是否已经生成了 Tables 类。
    }

    private val nameManager = TablesPropertyNamer()

    fun generate() {
        if (!AllInTablesEnable.value) return
        val packageName = AllInTablesPackage.value
            ?: return logger.warn(
                "The KSP needs to generate the class Tables " +
                        "(you have configured 'processor.allInTables.enable' located in the 'mybatis-flex.config' file)" +
                        " but does not specify under which package it will be generated, and cannot be generated."
            )
        if (isExists) return logger.warn("Tables has exists.")
        val fileSpec = FileSpec.builder(packageName, AllInTablesClassName.value)
            .addType(
                TypeSpec.objectBuilder(AllInTablesClassName.value)
                    .addKdoc(
                        """
                        |This file is automatically generated by the ksp of mybatis-flex, do not modify this file.
                        """.trimMargin()
                    )
                    .addProperties(nameManager.renameProperties(properties))
                    .build()
            )
            .suppressDefault()
            .build()
        fileSpec.write(true, *files)
        isExists = true
    }
}